﻿using Gateway.Common.Enums;
using Gateway.IApplication.UserMessage;
using Gateway.IApplication.UserMessage.Input;
using Gateway.IQuery.User;
using Aurora.SingalR.Hubs;
using Microsoft.AspNetCore.SignalR;

namespace Gateway.UI.Api.Hubs
{
    /// <summary>
    /// hub 工厂
    /// </summary>
    public class HubHandler : IHubHandler
    {
        // private readonly ISignalrUserClientApp _userClientApp;
        private readonly IUserMessageApp _userMessageApp;
        private readonly IServiceScopeFactory _scopeFactory;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="scopeFactory"></param>
        /// <param name="userMessageApp"></param>
        public HubHandler(IServiceScopeFactory scopeFactory, IUserMessageApp userMessageApp)
        {
            _scopeFactory = scopeFactory;
            _userMessageApp = userMessageApp;
        }

        /// <summary>
        /// 发送消息
        /// </summary>
        /// <param name="clients"></param>
        /// <param name="message"></param>
        public async Task SendMessage(IHubCallerClients clients, HubMessage message)
        {
            if (message.Type.Equals("all"))
            {
                await NotifyAll(clients, message.Creator, message.Intro, message.MessageId);
            }
            else
            {
                await SendMessage(clients, message.User.ToString(), message.Intro, message.Creator,
                    message.MessageId);
            }
        }

        /// <summary>
        /// 发送消息
        /// </summary>
        /// <param name="clients"></param>
        /// <param name="message"></param>
        public async Task SendMessage(IHubClients clients, HubMessage message)
        {
            if (message.Type.Equals("all"))
            {
                await NotifyAll(clients, message.Creator, message.Intro, message.MessageId);
            }
            else
            {
                await SendMessage(clients, message.User.ToString(), message.Intro, message.Creator,
                    message.MessageId);
            }
        }

        /// <summary>
        /// 发送消息
        /// </summary>
        /// <param name="clients"></param>
        /// <param name="user"></param>
        /// <param name="message"></param>
        /// <param name="creator"></param>
        /// <param name="messageId"></param>
        public async Task SendMessage(IHubCallerClients clients, string user, string message, string creator,
            string messageId)
        {
            var clientIds = await _userMessageApp.GetConnectionIdByAccount(user);
            foreach (var item in clientIds)
            {
                var userClient = clients.Client(item);
                if (userClient != null)
                    await userClient.SendAsync("ReceiveMessage", new HubMessage()
                    {
                        Type = SendTypeEnum.Person.Value,
                        Creator = creator,
                        Message = message, MessageId = messageId
                    });
            }
        }

        /// <summary>
        /// 通知所有人
        /// </summary>
        /// <param name="clients"></param>
        /// <param name="creator"></param>
        /// <param name="message"></param>
        /// <param name="messageId"></param>
        public async Task NotifyAll(IHubCallerClients clients, string creator, string message, string messageId)
        {
            await clients.All.SendAsync("ReceiveMessage", new HubMessage()
            {
                Type = SendTypeEnum.All.Value,
                Creator = creator,
                Message = message, MessageId = messageId
            });
        }

        /// <summary>
        /// 发送消息
        /// </summary>
        /// <param name="clients"></param>
        /// <param name="message"></param>
        public async Task Send(IHubCallerClients clients, HubMessage message)
        {
            message.Intro = ReplaceHtmlHelper.Instance.ReplaceHtmlTag(message.Message?.ToString()??"");
            if (message.Intro.Length > 20)
            {
                message.Intro = message.Intro.Substring(0, 20) + "...";
            }

            await CreateUserMessage(message);
            await SendMessage(clients, message);
        }

        /// <summary>
        /// 创建用户消息
        /// </summary>
        /// <param name="message"></param>
        /// <returns></returns>
        private Task CreateUserMessage(HubMessage message)
        {
            Task.Factory.StartNew(async () =>
            {
                using var scope = _scopeFactory.CreateScope();
                List<CreateUserMessageInput> messages =
                    new List<CreateUserMessageInput>();
                var messageApp = scope.ServiceProvider.GetService<IUserMessageApp>();
                if (message.Type.Equals("all"))
                {
                    var userQueryApp = scope.ServiceProvider.GetService<IUserQuery>();
                    var users = await userQueryApp.GetAllUserId();
                    if (users.Count > 0)
                    {
                        foreach (var item in users)
                        {
                            messages.Add(new CreateUserMessageInput()
                            {
                                Account = item,
                                Message = message.Message.ToString(),
                                Sender = message.Creator,
                                SendType = SendTypeEnum.FromValue(message.Type)
                            });
                        }
                    }
                }
                else
                {
                    messages.Add(new CreateUserMessageInput()
                    {
                        Account = message.User.ToString(),
                        Message = message.Message.ToString(),
                        Sender = message.Creator,
                        SendType = SendTypeEnum.FromValue(message.Type)
                    });
                }

                if (messages.Count > 0)
                {
                    foreach (var item in messages)
                    {
                        await messageApp.CreateMessage(item);
                    }
                }
            }, TaskCreationOptions.LongRunning);
            return Task.CompletedTask;
        }

        /// <summary>
        /// 发送消息
        /// </summary>
        /// <param name="clients"></param>
        /// <param name="user"></param>
        /// <param name="message"></param>
        /// <param name="creator"></param>
        /// <param name="messageId"></param>
        public async Task SendMessage(IHubClients clients, string user, string message, string creator,
            string messageId)
        {
            var clientIds = await _userMessageApp.GetConnectionIdByAccount(user);
            foreach (var item in clientIds)
            {
                var userClient = clients.Client(item);
                if (userClient != null)
                    await userClient.SendAsync("ReceiveMessage", new HubMessage()
                    {
                        Type = SendTypeEnum.Person.Value,
                        Creator = creator,
                        Message = message, MessageId = messageId
                    });
            }
        }

        /// <summary>
        /// 通知所有人
        /// </summary>
        /// <param name="clients"></param>
        /// <param name="creator"></param>
        /// <param name="message"></param>
        /// <param name="messageId"></param>
        public async Task NotifyAll(IHubClients clients, string creator, string message, string messageId)
        {
            await clients.All.SendAsync("ReceiveMessage", new HubMessage()
            {
                Type = SendTypeEnum.All.Value,
                Creator = creator,
                Message = message, MessageId = messageId
            });
        }

        /// <summary>
        /// 发送消息
        /// </summary>
        /// <param name="clients"></param>
        /// <param name="message"></param>
        public async Task Send(IHubClients clients, HubMessage message)
        {
            message.Intro = ReplaceHtmlHelper.Instance.ReplaceHtmlTag(message.Message?.ToString() ?? "");
            if (message.Intro.Length > 20)
            {
                message.Intro = message.Intro.Substring(0, 20) + "...";
            }

            await CreateUserMessage(message);
            await SendMessage(clients, message);
        }
    }
}